# -*- coding: utf-8 -*-
import os
import sqlite3
from tkinter import *
from tkinter import messagebox, ttk
from tkinter.font import Font

class Book:
    def __init__(self, title, author, isbn, available=True, category_id=None):
        self.title, self.author, self.isbn, self.available, self.category_id = title, author, isbn, available, category_id

    def __str__(self):
        return f'书名：{self.title}\n作者：{self.author}\nISBN：{self.isbn}\n状态：{"可借阅" if self.available else "已借出"}'

class Library:
    def __init__(self, db_path='library.db'):
        self.conn = sqlite3.connect(db_path)
        self._init_db()
        self.categories = self._load_categories()
        self.books = self._load_books()

    def _init_db(self):
        self.conn.executescript('''
            CREATE TABLE IF NOT EXISTS categories (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL,
                parent_id INTEGER,
                FOREIGN KEY(parent_id) REFERENCES categories(id)
            );
            CREATE TABLE IF NOT EXISTS books (
                isbn TEXT PRIMARY KEY,
                title TEXT NOT NULL,
                author TEXT NOT NULL,
                available BOOLEAN DEFAULT TRUE,
                category_id INTEGER,
                FOREIGN KEY(category_id) REFERENCES categories(id)
            );
            CREATE TABLE IF NOT EXISTS borrow_records (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                isbn TEXT NOT NULL,
                borrower TEXT NOT NULL,
                borrow_date TEXT NOT NULL,
                return_date TEXT,
                FOREIGN KEY(isbn) REFERENCES books(isbn)
            );
        ''')
        self.conn.commit()

    def _load_categories(self):
        return [{'id': row[0], 'name': row[1], 'parent_id': row[2]} 
                for row in self.conn.execute('SELECT id, name, parent_id FROM categories')]

    def _load_books(self):
        return [Book(title=row[1], author=row[2], isbn=row[0], available=row[3]) 
                for row in self.conn.execute('SELECT isbn, title, author, available FROM books')]

    def add_category(self, name, parent_id=None):
        try:
            self.conn.execute('INSERT INTO categories (name, parent_id) VALUES (?, ?)', (name, parent_id))
            self.conn.commit()
            self.categories = self._load_categories()
            return True, '分类添加成功'
        except sqlite3.Error as e:
            return False, f'添加分类失败：{str(e)}'

    def get_category_tree(self):
        tree = {None: []}
        for cat in self.categories:
            if cat['parent_id'] not in tree:
                tree[cat['parent_id']] = []
            tree[cat['parent_id']].append(cat)
        return tree

    def add_book(self, book, category_id=None):
        try:
            self.conn.execute('''INSERT INTO books (isbn, title, author, available, category_id)
                                VALUES (?, ?, ?, ?, ?)''',
                             (book.isbn, book.title, book.author, book.available, category_id))
            self.conn.commit()
            return True, '图书添加成功！'
        except sqlite3.IntegrityError:
            return False, '该ISBN已存在'

    def remove_book(self, isbn):
        """删除指定ISBN的图书"""
        try:
            # 先检查图书是否存在
            cursor = self.conn.execute('SELECT category_id FROM books WHERE isbn = ?', (isbn,))
            result = cursor.fetchone()
            if not result:
                return False, '未找到该ISBN的图书'
            
            # 删除图书
            self.conn.execute('DELETE FROM books WHERE isbn = ?', (isbn,))
            self.conn.commit()
            
            # 重新加载图书数据
            self.books = self._load_books()
            return True, '图书删除成功！'
        except sqlite3.Error as e:
            return False, f'删除图书失败：{str(e)}'

    def search_books(self, keyword):
        cursor = self.conn.execute('''SELECT isbn, title, author, available FROM books
                                      WHERE LOWER(title) LIKE ? OR LOWER(author) LIKE ?''',
                                   (f'%{keyword.lower()}%', f'%{keyword.lower()}%'))
        return [Book(title=row[1], author=row[2], isbn=row[0], available=row[3]) for row in cursor.fetchall()]

    def borrow_book(self, isbn, borrower):
        cursor = self.conn.execute('SELECT available FROM books WHERE isbn = ?', (isbn,))
        result = cursor.fetchone()
        if not result:
            return False, '图书不存在'
        if not result[0]:
            return False, '图书已被借出'
        
        self.conn.execute('UPDATE books SET available = FALSE WHERE isbn = ?', (isbn,))
        from datetime import datetime
        borrow_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        self.conn.execute('''INSERT INTO borrow_records (isbn, borrower, borrow_date)
                            VALUES (?, ?, ?)''', (isbn, borrower, borrow_date))
        self.conn.commit()
        return True, '借阅成功'

    def return_book(self, isbn):
        cursor = self.conn.execute('SELECT available FROM books WHERE isbn = ?', (isbn,))
        result = cursor.fetchone()
        if not result:
            return False, '图书不存在'
        if result[0]:
            return False, '图书未被借出'
        
        self.conn.execute('UPDATE books SET available = TRUE WHERE isbn = ?', (isbn,))
        from datetime import datetime
        return_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        self.conn.execute('''UPDATE borrow_records 
                            SET return_date = ? 
                            WHERE isbn = ? AND return_date IS NULL''', 
                         (return_date, isbn))
        self.conn.commit()
        return True, '归还成功'

    def get_borrow_history(self, isbn=None):
        query = '''SELECT br.isbn, b.title, br.borrower, br.borrow_date, br.return_date 
                  FROM borrow_records br
                  JOIN books b ON br.isbn = b.isbn'''
        params = []
        if isbn:
            query += ' WHERE br.isbn = ?'
            params.append(isbn)
        query += ' ORDER BY br.borrow_date DESC'
        return self.conn.execute(query, params).fetchall()

    def delete_category(self, category_id):
        cursor = self.conn.execute('SELECT COUNT(*) FROM categories WHERE parent_id = ?', (category_id,))
        if cursor.fetchone()[0] > 0:
            return False, '该分类下还有子分类，无法删除'
            
        cursor = self.conn.execute('SELECT COUNT(*) FROM books WHERE category_id = ?', (category_id,))
        if cursor.fetchone()[0] > 0:
            return False, '该分类下还有图书，无法删除'
            
        self.conn.execute('DELETE FROM categories WHERE id = ?', (category_id,))
        self.conn.commit()
        self.categories = self._load_categories()
        return True, '分类删除成功'

class ModernButton(Frame):
    def __init__(self, parent, text="", command=None, bg_color="#4A90E2", hover_color="#357ABD", 
                 text_color="white", font_size=10, width=180, height=60, **kwargs):
        super().__init__(parent, **kwargs)
        self.command, self.bg_color, self.hover_color, self.text_color = command, bg_color, hover_color, text_color
        
        self.canvas = Canvas(self, width=width, height=height, highlightthickness=0, relief='flat', borderwidth=0)
        self.canvas.pack()
        
        self.bg_rect = self.create_rounded_rect(self.canvas, 2, 2, width-2, height-2, radius=8, fill=bg_color, outline="")
        self.text_item = self.canvas.create_text(width//2, height//2, text=text, 
                                               fill=text_color, font=('微软雅黑', font_size, 'bold'))
        
        for event, handler in [('<Button-1>', self._on_click), ('<Enter>', self._on_enter), 
                             ('<Leave>', self._on_leave)]:
            self.canvas.bind(event, handler)
            self.bind(event, handler)
    
    @staticmethod
    def create_rounded_rect(canvas, x1, y1, x2, y2, radius=25, **kwargs):
        points = []
        for x, y in [(x1, y1 + radius), (x1, y1), (x1 + radius, y1),
                     (x2 - radius, y1), (x2, y1), (x2, y1 + radius),
                     (x2, y2 - radius), (x2, y2), (x2 - radius, y2),
                     (x1 + radius, y2), (x1, y2), (x1, y2 - radius)]:
            points.extend([x, y])
        return canvas.create_polygon(points, smooth=True, **kwargs)
    
    def _on_click(self, event):
        if self.command:
            self.command()
    
    def _on_enter(self, event):
        self.canvas.itemconfig(self.bg_rect, fill=self.hover_color)
    
    def _on_leave(self, event):
        self.canvas.itemconfig(self.bg_rect, fill=self.bg_color)
    
    def config_text(self, text):
        self.canvas.itemconfig(self.text_item, text=text)

class LibraryApp:
    def __init__(self, root):
        self.root = root
        self.root.title('📚 现代图书馆管理系统')
        self.root.geometry('1200x800')
        self.root.configure(bg='#F5F7FA')
        
        self.setup_styles()
        self.library = Library()
        self.current_parent_id = None
        self.parent_stack = []
        self.selected_category_id = None
        self.cat_btns = {}
        self.folder_icon, self.book_icon = '📁', '📖'
        self.path_buttons = []
        self.is_search_mode = False
        self.search_keyword = None
        
        self.setup_context_menus()
        self.create_main_interface()
        self.show_category_grid(self.current_parent_id)
        
        # 绑定 Delete 键和回车键
        self.root.bind('<Delete>', self.on_delete_key)
        self.root.bind('<Return>', self.on_return_key)

    def setup_styles(self):
        self.colors = {
            'primary': '#4A90E2', 'primary_hover': '#357ABD', 'secondary': '#7ED321',
            'danger': '#D0021B', 'warning': '#F5A623', 'background': '#F5F7FA',
            'card_bg': '#FFFFFF', 'text_primary': '#2C3E50', 'text_secondary': '#7F8C8D',
            'border': '#E1E8ED'
        }
        
        self.fonts = {
            'title': Font(family='微软雅黑', size=16, weight='bold'),
            'subtitle': Font(family='微软雅黑', size=12, weight='bold'),
            'body': Font(family='微软雅黑', size=10),
            'small': Font(family='微软雅黑', size=9)
        }
        
        style = ttk.Style()
        style.theme_use('clam')
        style.configure('Modern.Treeview', background='white', foreground=self.colors['text_primary'],
                       rowheight=35, fieldbackground='white', borderwidth=0, relief='flat')
        style.configure('Modern.Treeview.Heading', background=self.colors['primary'],
                       foreground='white', font=self.fonts['subtitle'])

    def setup_context_menus(self):
        menu_config = {'tearoff': 0, 'font': self.fonts['body'], 'bg': 'white',
                      'fg': self.colors['text_primary'], 'activebackground': self.colors['primary'],
                      'activeforeground': 'white'}
        
        self.context_menu = Menu(self.root, **menu_config)
        self.category_menu = Menu(self.root, **menu_config)
        self.book_menu = Menu(self.root, **menu_config)

        self.context_menu.add_command(label="📁 新建分类", command=self.add_category)
        self.context_menu.add_command(label="📖 新建图书", command=self.add_book)

        self.category_menu.add_command(label="📁 新建分类", command=self.add_category)
        self.category_menu.add_command(label="🗑️ 删除分类", command=self.delete_category)
        self.category_menu.add_command(label="📖 新建图书", command=self.add_book)

        self.book_menu.add_command(label="🗑️ 删除图书", command=self.delete_book)
        self.book_menu.add_command(label="📤 借出图书", command=self.borrow_book)
        self.book_menu.add_command(label="📥 归还图书", command=self.return_book)

    def create_main_interface(self):
        self.create_header()
        self.create_navigation()
        self.create_main_content()

    def create_header(self):
        header_frame = Frame(self.root, bg=self.colors['primary'], height=80)
        header_frame.pack(fill='x', padx=0, pady=0)
        header_frame.pack_propagate(False)
        
        Label(header_frame, text='📚 现代图书馆管理系统', font=self.fonts['title'],
              bg=self.colors['primary'], fg='white').pack(side='left', padx=20, pady=25)
        
        search_frame = Frame(header_frame, bg=self.colors['primary'])
        search_frame.pack(side='right', padx=20, pady=20)
        
        self.search_var = StringVar()
        Entry(search_frame, textvariable=self.search_var, font=self.fonts['body'],
              width=30, relief='flat', bd=5, bg='white').pack(side='left', padx=(0, 10))
        
        Button(search_frame, text='🔍 搜索', command=self.search_books,
               bg='white', fg=self.colors['primary'], font=self.fonts['body'],
               relief='flat', padx=15, pady=5).pack(side='left')

    def create_navigation(self):
        nav_frame = Frame(self.root, bg='white', height=50)
        nav_frame.pack(fill='x', padx=0, pady=0)
        nav_frame.pack_propagate(False)
        
        Frame(self.root, bg='#E1E8ED', height=1).pack(fill='x')
        
        Button(nav_frame, text="⬅️ 返回", command=self.go_back,
               bg='white', fg=self.colors['primary'], font=self.fonts['body'],
               relief='flat', padx=10, pady=5).pack(side='left', padx=10, pady=10)
        
        self.path_frame = Frame(nav_frame, bg='white')
        self.path_frame.pack(fill='both', expand=True, padx=20, pady=10)
        
        Label(self.path_frame, text="📍 当前位置：", font=self.fonts['body'],
              bg='white', fg=self.colors['text_secondary']).pack(side='left')
        
        self.path_buttons_frame = Frame(self.path_frame, bg='white')
        self.path_buttons_frame.pack(side='left', fill='x', expand=True, padx=(10, 0))

    def create_main_content(self):
        main_container = Frame(self.root, bg=self.colors['background'])
        main_container.pack(fill='both', expand=True, padx=20, pady=20)
        
        self.content_card = Frame(main_container, bg=self.colors['card_bg'], relief='flat', bd=0)
        self.content_card.pack(fill='both', expand=True)
        
        shadow = Frame(self.content_card.master, bg='#E1E8ED', height=2)
        shadow.place(in_=self.content_card, x=2, y=2, relwidth=1, relheight=1)
        self.content_card.lift()
        
        self.create_scrollable_area()

    def create_scrollable_area(self):
        self.canvas = Canvas(self.content_card, bg=self.colors['card_bg'], highlightthickness=0)
        self.scrollbar = ttk.Scrollbar(self.content_card, orient="vertical", command=self.canvas.yview)
        self.scrollable_frame = Frame(self.canvas, bg=self.colors['card_bg'])

        self.scrollable_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
        
        # 为所有相关组件绑定右键菜单事件
        self.scrollable_frame.bind("<Button-3>", self.show_context_menu)
        self.canvas.bind("<Button-3>", self.show_context_menu)
        self.content_card.bind("<Button-3>", self.show_context_menu)

        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        self.canvas.pack(side="left", fill="both", expand=True, padx=20, pady=20)
        self.scrollbar.pack(side="right", fill="y", pady=20)

        self.canvas.bind("<MouseWheel>", lambda e: self.canvas.yview_scroll(int(-1*(e.delta/120)), "units"))
        
        self.category_grid_frame = self.scrollable_frame

    def show_category_grid(self, parent_id):
        for widget in self.category_grid_frame.winfo_children():
            widget.destroy()
        self.cat_btns.clear()

        self.current_parent_id = parent_id
        self.update_path_display()

        categories = [cat for cat in self.library.categories if cat['parent_id'] == parent_id]
        
        if not categories:
            self.show_books_in_category(parent_id)
            return

        self.create_category_grid(categories)

    def create_category_grid(self, categories):
        title_text = "📁 所有分类" if self.current_parent_id is None else \
                    f"📁 {next((cat['name'] for cat in self.library.categories if cat['id'] == self.current_parent_id), '未知分类')}"
        
        Label(self.category_grid_frame, text=title_text, font=self.fonts['title'],
              bg=self.colors['card_bg'], fg=self.colors['text_primary']).grid(
              row=0, column=0, columnspan=4, pady=(0, 20), sticky='w')

        row, col, max_cols = 1, 0, 4
        for category in categories:
            card_frame = self.create_category_card(category)
            card_frame.grid(row=row, column=col, padx=15, pady=15, sticky='nsew')
            self.cat_btns[category['id']] = card_frame
            
            col += 1
            if col >= max_cols:
                col = 0
                row += 1

        for i in range(max_cols):
            self.category_grid_frame.grid_columnconfigure(i, weight=1)

    def create_category_card(self, category):
        card_frame = Frame(self.category_grid_frame, bg='white', relief='flat', bd=0)
        canvas = Canvas(card_frame, width=200, height=120, bg='white', highlightthickness=0, relief='flat')
        canvas.pack(padx=5, pady=5)
        
        # 创建背景矩形
        bg_rect = ModernButton.create_rounded_rect(canvas, 5, 5, 195, 115, radius=10, 
                                                 fill='#F8F9FA', outline='#E1E8ED', width=1)
        
        # 创建选中状态指示器（默认隐藏）
        selected_indicator = canvas.create_rectangle(0, 0, 4, 120, fill=self.colors['primary'], outline='')
        canvas.itemconfig(selected_indicator, state='hidden')
        
        canvas.create_text(100, 35, text='📁', font=('微软雅黑', 24))
        canvas.create_text(100, 75, text=category['name'], font=self.fonts['subtitle'],
                         fill=self.colors['text_primary'])
        
        # 从数据库直接查询子分类和图书数量
        subcats_count = len([cat for cat in self.library.categories if cat['parent_id'] == category['id']])
        cursor = self.library.conn.execute('SELECT COUNT(*) FROM books WHERE category_id = ?', (category['id'],))
        books_count = cursor.fetchone()[0]
        
        canvas.create_text(100, 95, text=f"{subcats_count} 个子分类, {books_count} 本图书",
                         font=self.fonts['small'], fill=self.colors['text_secondary'])
        
        def on_enter(e):
            if self.selected_category_id != category['id']:
                canvas.itemconfig(bg_rect, fill='#E3F2FD')
        
        def on_leave(e):
            if self.selected_category_id != category['id']:
                canvas.itemconfig(bg_rect, fill='#F8F9FA')
        
        def on_click(e):
            self.on_category_click(category['id'])
            # 更新所有卡片的选中状态
            for cat_id, btn in self.cat_btns.items():
                btn_canvas = btn.winfo_children()[0]
                if cat_id == category['id']:
                    btn_canvas.itemconfig(selected_indicator, state='normal')
                    btn_canvas.itemconfig(bg_rect, fill='#E3F2FD')
                else:
                    btn_canvas.itemconfig(selected_indicator, state='hidden')
                    btn_canvas.itemconfig(bg_rect, fill='#F8F9FA')
        
        for event, handler in [
            ('<Button-1>', on_click),
            ('<Double-Button-1>', lambda e: self.on_category_double_click(category['id'])),
            ('<Button-3>', lambda e: self.on_category_right_click(e, category['id'])),
            ('<Enter>', on_enter),
            ('<Leave>', on_leave)
        ]:
            canvas.bind(event, handler)
        
        # 如果是当前选中的分类，显示选中状态
        if self.selected_category_id == category['id']:
            canvas.itemconfig(selected_indicator, state='normal')
            canvas.itemconfig(bg_rect, fill='#E3F2FD')
        
        return card_frame

    def show_books_in_category(self, category_id):
        for widget in self.category_grid_frame.winfo_children():
            widget.destroy()

        self.current_parent_id = category_id
        self.update_path_display()

        cursor = self.library.conn.execute(
            'SELECT isbn, title, author, available FROM books' + 
            (' WHERE category_id = ?' if category_id else ''), 
            (category_id,) if category_id else ())
        books = cursor.fetchall()

        title_text = f"📖 {next((cat['name'] for cat in self.library.categories if cat['id'] == category_id), '未知分类')} - 图书列表" if category_id else "📖 所有图书"
        
        Label(self.category_grid_frame, text=title_text, font=self.fonts['title'],
              bg=self.colors['card_bg'], fg=self.colors['text_primary']).grid(
              row=0, column=0, columnspan=2, pady=(0, 20), sticky='w')

        if not books:
            empty_frame = Frame(self.category_grid_frame, bg=self.colors['card_bg'])
            empty_frame.grid(row=1, column=0, columnspan=2, pady=50)
            
            Label(empty_frame, text='📚', font=('微软雅黑', 48),
                  bg=self.colors['card_bg'], fg=self.colors['text_secondary']).pack()
            Label(empty_frame, text='该分类下暂无图书', font=self.fonts['subtitle'],
                  bg=self.colors['card_bg'], fg=self.colors['text_secondary']).pack(pady=10)
            
            Button(empty_frame, text='📖 添加第一本图书', command=self.add_book,
                   bg=self.colors['primary'], fg='white', font=self.fonts['body'],
                   relief='flat', padx=20, pady=10).pack(pady=10)
            return

        self.create_modern_book_list(books)

    def create_modern_book_list(self, books):
        tree_frame = Frame(self.category_grid_frame, bg=self.colors['card_bg'])
        tree_frame.grid(row=1, column=0, sticky='nsew', padx=0, pady=0)
        
        self.book_tree = ttk.Treeview(tree_frame, columns=('title', 'author', 'isbn', 'status'),
                                    show='headings', style='Modern.Treeview')
        
        for col, text in [('title', '📖 书名'), ('author', '✍️ 作者'),
                         ('isbn', '🔢 ISBN'), ('status', '📊 状态')]:
            self.book_tree.heading(col, text=text)
        
        self.book_tree.column('title', width=250, anchor='w')
        self.book_tree.column('author', width=150, anchor='w')
        self.book_tree.column('isbn', width=150, anchor='center')
        self.book_tree.column('status', width=100, anchor='center')
        
        tree_scrollbar = ttk.Scrollbar(tree_frame, orient="vertical", command=self.book_tree.yview)
        self.book_tree.configure(yscrollcommand=tree_scrollbar.set)
        
        self.book_tree.pack(side='left', fill='both', expand=True)
        tree_scrollbar.pack(side='right', fill='y')
        
        for book in books:
            status = '✅ 可借阅' if book[3] else '❌ 已借出'
            tags = ('available',) if book[3] else ('borrowed',)
            self.book_tree.insert('', 'end', values=(book[1], book[2], book[0], status), tags=tags)
        
        self.book_tree.tag_configure('available', background='#E8F5E8')
        self.book_tree.tag_configure('borrowed', background='#FFE8E8')
        
        self.book_tree.bind('<Button-3>', self.show_context_menu)
        self.book_tree.bind('<Delete>', self.on_delete_key)
        
        self.category_grid_frame.grid_rowconfigure(1, weight=1)
        self.category_grid_frame.grid_columnconfigure(0, weight=1)

    def update_path_display(self):
        for widget in self.path_buttons_frame.winfo_children():
            widget.destroy()
        self.path_buttons.clear()

        Button(self.path_buttons_frame, text="🏠 根目录",
               command=lambda: self.navigate_to_category(None),
               bg='white', fg=self.colors['primary'], font=self.fonts['body'],
               relief='flat', padx=10, pady=5).pack(side='left')
        
        if self.current_parent_id is None:
            return

        path = []
        current_id = self.current_parent_id
        while current_id is not None:
            category = next((cat for cat in self.library.categories if cat['id'] == current_id), None)
            if category:
                path.insert(0, category)
                current_id = category['parent_id']
            else:
                break

        for category in path:
            Label(self.path_buttons_frame, text=" ▶ ", bg='white',
                  fg=self.colors['text_secondary'], font=self.fonts['body']).pack(side='left')
            
            Button(self.path_buttons_frame, text=category['name'],
                   command=lambda cid=category['id']: self.navigate_to_category(cid),
                   bg='white', fg=self.colors['primary'], font=self.fonts['body'],
                   relief='flat', padx=10, pady=5).pack(side='left')

    def navigate_to_category(self, category_id):
        if category_id == self.current_parent_id:
            return
            
        if hasattr(self, 'search_var'):
            self.search_var.set('')
        if hasattr(self, 'is_search_mode'):
            self.is_search_mode = False
            self.search_keyword = None
            
        self.show_category_grid(category_id)

    def on_category_click(self, category_id):
        self.selected_category_id = category_id

    def on_category_double_click(self, category_id):
        self.show_category_grid(category_id)

    def on_category_right_click(self, event, category_id):
        self.on_category_click(category_id)
        self.category_menu.post(event.x_root, event.y_root)

    def show_context_menu(self, event):
        """显示上下文菜单"""
        try:
            # 检查是否点击在图书列表上
            if hasattr(self, 'book_tree') and self.book_tree.winfo_exists():
                item = self.book_tree.identify_row(event.y)
                if item:
                    self.book_tree.selection_set(item)
                    self.book_menu.post(event.x_root, event.y_root)
                    return

            # 检查是否点击在分类卡片上
            if hasattr(self, 'cat_btns'):
                for category_id, card_frame in self.cat_btns.items():
                    if card_frame.winfo_exists() and card_frame.winfo_containing(event.x_root, event.y_root):
                        self.selected_category_id = category_id
                        self.category_menu.post(event.x_root, event.y_root)
                        return

            # 如果都不是，显示默认的上下文菜单
            self.context_menu.post(event.x_root, event.y_root)
        except Exception:
            # 如果出错，至少显示默认菜单
            self.context_menu.post(event.x_root, event.y_root)

    def search_books(self):
        keyword = self.search_var.get().strip()
        if not keyword:
            messagebox.showwarning('警告', '请输入搜索关键词！')
            return
        
        books = self.library.search_books(keyword)
        if not books:
            messagebox.showinfo('搜索结果', '未找到相关图书！')
            return
        
        self.show_search_results(books, keyword)

    def show_search_results(self, books, keyword):
        for widget in self.category_grid_frame.winfo_children():
            widget.destroy()

        Label(self.category_grid_frame, text=f"🔍 搜索结果：'{keyword}' ({len(books)} 本图书)",
              font=self.fonts['title'], bg=self.colors['card_bg'],
              fg=self.colors['text_primary']).grid(row=0, column=0, columnspan=2,
              pady=(0, 20), sticky='w')

        book_data = [(book.title, book.author, book.isbn, book.available) for book in books]
        self.create_modern_book_list(book_data)
        
        self.is_search_mode = True
        self.search_keyword = keyword

    def create_modern_dialog(self, title, icon):
        dialog = Toplevel(self.root)
        dialog.title(f"{icon} {title}")
        dialog.geometry("400x400")
        dialog.configure(bg='white')
        dialog.transient(self.root)
        dialog.grab_set()
        
        dialog.geometry("+%d+%d" % (self.root.winfo_rootx() + 50, self.root.winfo_rooty() + 50))
        
        title_frame = Frame(dialog, bg=self.colors['primary'], height=60)
        title_frame.pack(fill='x')
        title_frame.pack_propagate(False)
        
        Label(title_frame, text=f"{icon} {title}", font=self.fonts['title'],
              bg=self.colors['primary'], fg='white').pack(pady=20)
        
        # 创建内容框架
        content_frame = Frame(dialog, bg='white')
        content_frame.pack(fill='both', expand=True, padx=20, pady=20)
        
        return dialog, content_frame

    def create_dialog_buttons(self, dialog, ok_command, cancel_command):
        button_frame = Frame(dialog, bg='white')
        button_frame.pack(side='bottom', fill='x', padx=20, pady=20)
        
        Button(button_frame, text='取消', command=cancel_command,
               bg='#E0E0E0', fg=self.colors['text_primary'], font=self.fonts['body'],
               relief='flat', padx=20, pady=8).pack(side='right', padx=(10, 0))
        
        Button(button_frame, text='确定', command=ok_command,
               bg=self.colors['primary'], fg='white', font=self.fonts['body'],
               relief='flat', padx=20, pady=8).pack(side='right')

    def add_category(self):
        dialog, content_frame = self.create_modern_dialog("添加分类", "📁")
        
        Label(content_frame, text='分类名称：', font=self.fonts['body']).pack(pady=5)
        name_entry = Entry(content_frame, font=self.fonts['body'], width=30)
        name_entry.pack(pady=5)
        name_entry.focus_set()

        def on_ok():
            name = name_entry.get().strip()
            if not name:
                messagebox.showwarning('警告', '分类名称不能为空！')
                return
            success, msg = self.library.add_category(name, self.current_parent_id)
            if success:
                dialog.destroy()
                # 重新加载分类数据
                self.library.categories = self.library._load_categories()
                # 刷新显示
                self.show_category_grid(self.current_parent_id)
            else:
                messagebox.showerror('错误', msg)

        self.create_dialog_buttons(dialog, on_ok, dialog.destroy)

    def add_book(self):
        if not self.current_parent_id:
            messagebox.showwarning('警告', '请先进入某个分类！')
            return

        dialog, content_frame = self.create_modern_dialog("添加图书", "📖")
        
        # 创建输入框和变量
        title_var = StringVar()
        author_var = StringVar()
        isbn_var = StringVar()
        
        # 创建输入框
        Label(content_frame, text='书名：', font=self.fonts['body']).pack(pady=5)
        title_entry = Entry(content_frame, textvariable=title_var, font=self.fonts['body'], width=30)
        title_entry.pack(pady=5)
        
        Label(content_frame, text='作者：', font=self.fonts['body']).pack(pady=5)
        author_entry = Entry(content_frame, textvariable=author_var, font=self.fonts['body'], width=30)
        author_entry.pack(pady=5)
        
        Label(content_frame, text='ISBN：', font=self.fonts['body']).pack(pady=5)
        isbn_entry = Entry(content_frame, textvariable=isbn_var, font=self.fonts['body'], width=30)
        isbn_entry.pack(pady=5)
        
        title_entry.focus_set()

        def on_ok():
            title = title_var.get().strip()
            author = author_var.get().strip()
            isbn = isbn_var.get().strip()
            
            if not all([title, author, isbn]):
                messagebox.showwarning('警告', '所有字段都不能为空！')
                return
                
            book = Book(title, author, isbn)
            success, msg = self.library.add_book(book, self.current_parent_id)
            
            if success:
                dialog.destroy()
                self.show_books_in_category(self.current_parent_id)
            else:
                messagebox.showerror('错误', msg)

        self.create_dialog_buttons(dialog, on_ok, dialog.destroy)

    def delete_category(self):
        if not self.selected_category_id:
            messagebox.showwarning('警告', '请先选择要删除的分类！')
            return
            
        if messagebox.askyesno('确认删除', '确定要删除该分类吗？'):
            success, msg = self.library.delete_category(self.selected_category_id)
            if success:
                self.selected_category_id = None  # 清除选中状态
                self.show_category_grid(self.current_parent_id)
            else:
                messagebox.showerror('错误', msg)

    def delete_book(self):
        """删除选中的图书"""
        book = self._get_selected_book('删除')
        if not book:
            return

        if messagebox.askyesno('确认删除', f'确定要删除《{book["title"]}》吗？'):
            success, msg = self.library.remove_book(book['isbn'])
            if success:
                # 保存当前分类ID
                current_category = self.current_parent_id
                # 刷新图书列表
                self.show_books_in_category(current_category)
            else:
                messagebox.showerror('错误', msg)

    def borrow_book(self):
        book = self._get_selected_book('借出')
        if not book:
            return
            
        if '已借出' in book['status']:
            messagebox.showwarning('警告', '该图书已被借出！')
            return

        dialog = self.create_modern_dialog("借出图书", "📤")
        
        Label(dialog, text=f'书名：{book["title"]}', font=self.fonts['body']).pack(pady=5)
        Label(dialog, text='借阅人：', font=self.fonts['body']).pack(pady=5)
        borrower_entry = Entry(dialog, font=self.fonts['body'], width=30)
        borrower_entry.pack(pady=5)
        borrower_entry.focus_set()

        def on_ok():
            borrower = borrower_entry.get().strip()
            if not borrower:
                messagebox.showwarning('警告', '请输入借阅人姓名！')
                return
            success, msg = self.library.borrow_book(book['isbn'], borrower)
            if success:
                messagebox.showinfo('成功', msg)
                dialog.destroy()
                self.show_books_in_category(self.current_parent_id)
            else:
                messagebox.showerror('错误', msg)

        self.create_dialog_buttons(dialog, on_ok, dialog.destroy)

    def return_book(self):
        book = self._get_selected_book('归还')
        if not book:
            return
            
        if '可借阅' in book['status']:
            messagebox.showwarning('警告', '该图书未被借出！')
            return

        if messagebox.askyesno('确认归还', f'确定要归还《{book["title"]}》吗？'):
            success, msg = self.library.return_book(book['isbn'])
            if success:
                messagebox.showinfo('成功', msg)
                self.show_books_in_category(self.current_parent_id)
            else:
                messagebox.showerror('错误', msg)

    def _get_selected_book(self, operation_name):
        if not hasattr(self, 'book_tree'):
            messagebox.showwarning('警告', '请先进入图书列表！')
            return None
            
        selected_items = self.book_tree.selection()
        if not selected_items:
            messagebox.showwarning('警告', f'请先选择要{operation_name}的图书！')
            return None
            
        selected_item = selected_items[0]
        values = self.book_tree.item(selected_item)['values']
        return {'title': values[0], 'author': values[1], 'isbn': values[2], 'status': values[3]}

    def on_delete_key(self, event):
        """处理 Delete 键按下事件"""
        try:
            # 检查是否在图书列表界面且有选中的图书
            if hasattr(self, 'book_tree') and self.book_tree.winfo_exists():
                selected_items = self.book_tree.selection()
                if selected_items:
                    # 删除选中的图书
                    book = self._get_selected_book('删除')
                    if book and messagebox.askyesno('确认删除', f'确定要删除《{book["title"]}》吗？'):
                        success, msg = self.library.remove_book(book['isbn'])
                        if success:
                            # 保存当前分类ID并刷新显示
                            current_category = self.current_parent_id
                            self.show_books_in_category(current_category)
                        else:
                            messagebox.showerror('错误', msg)
                    return

            # 检查是否有选中的分类
            if self.selected_category_id:
                if messagebox.askyesno('确认删除', '确定要删除该分类吗？'):
                    success, msg = self.library.delete_category(self.selected_category_id)
                    if success:
                        self.selected_category_id = None
                        self.show_category_grid(self.current_parent_id)
                    else:
                        messagebox.showerror('错误', msg)
                return

        except Exception:
            # 出错时不做任何操作
            pass

    def go_back(self):
        if self.is_search_mode:
            self.is_search_mode = False
            self.search_keyword = None
            if hasattr(self, 'search_var'):
                self.search_var.set('')
            self.show_category_grid(self.current_parent_id)
            return
            
        if self.current_parent_id is None:
            return
            
        current_cat = next((cat for cat in self.library.categories if cat['id'] == self.current_parent_id), None)
        if current_cat:
            self.navigate_to_category(current_cat['parent_id'])

    def on_return_key(self, event):
        """处理回车键按下事件"""
        try:
            # 检查是否有选中的分类
            if self.selected_category_id:
                # 打开选中的分类
                self.show_category_grid(self.selected_category_id)
        except Exception:
            # 出错时不做任何操作
            pass

if __name__ == '__main__':
    try:
        root = Tk()
        app = LibraryApp(root)
        root.mainloop()
    except Exception as e:
        messagebox.showerror("错误", f"应用程序启动失败: {e}")